From a98892e3b0404ba48ec5744f7ec7ada8eeb2dc31 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 16 Oct 2008 09:51:42 +0100 Subject: [PATCH] xentrace: trace power management events. Signed-off-by: Guanqun Lu --- tools/xentrace/formats | 4 ++++ xen/arch/x86/acpi/cpu_idle.c | 15 +++++++++++++++ xen/drivers/cpufreq/utility.c | 7 +++++++ xen/include/public/trace.h | 10 ++++++++++ 4 files changed, 36 insertions(+) diff --git a/tools/xentrace/formats b/tools/xentrace/formats index 84d8cc6841..5d84eec6b3 100644 --- a/tools/xentrace/formats +++ b/tools/xentrace/formats @@ -116,3 +116,7 @@ 0x0040f10e CPU%(cpu)d %(tsc)d (+%(reltsc)8d) shadow_emulate_resync_full [ gfn = 0x%(1)16x ] 0x0040f00f CPU%(cpu)d %(tsc)d (+%(reltsc)8d) shadow_emulate_resync_only [ gfn = 0x%(1)08x ] 0x0040f10f CPU%(cpu)d %(tsc)d (+%(reltsc)8d) shadow_emulate_resync_only [ gfn = 0x%(1)16x ] + +0x00801001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_freq_change [ %(1)dMHz -> %(2)dMHz ] +0x00802001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_entry [ C0 -> C%(1)d ] +0x00802002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_exit [ C%(1)d -> C0 ] diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 8d2aa88d41..176129489e 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -251,6 +252,9 @@ static void acpi_processor_idle(void) switch ( cx->type ) { case ACPI_STATE_C1: + /* Trace cpu idle entry */ + TRACE_1D(TRC_PM_IDLE_ENTRY, 1); + /* * Invoke C1. * Use the appropriate idle routine, the one that would @@ -261,6 +265,9 @@ static void acpi_processor_idle(void) else acpi_safe_halt(); + /* Trace cpu idle exit */ + TRACE_1D(TRC_PM_IDLE_EXIT, 1); + /* * TBD: Can't get time duration while in C1, as resumes * go to an ISR rather than here. Need to instrument @@ -272,12 +279,16 @@ static void acpi_processor_idle(void) case ACPI_STATE_C2: if ( local_apic_timer_c2_ok ) { + /* Trace cpu idle entry */ + TRACE_1D(TRC_PM_IDLE_ENTRY, 2); /* Get start time (ticks) */ t1 = inl(pmtmr_ioport); /* Invoke C2 */ acpi_idle_do_entry(cx); /* Get end time (ticks) */ t2 = inl(pmtmr_ioport); + /* Trace cpu idle exit */ + TRACE_1D(TRC_PM_IDLE_EXIT, 2); /* Re-enable interrupts */ local_irq_enable(); @@ -316,6 +327,8 @@ static void acpi_processor_idle(void) ACPI_FLUSH_CPU_CACHE(); } + /* Trace cpu idle entry */ + TRACE_1D(TRC_PM_IDLE_ENTRY, cx - &power->states[0]); /* * Before invoking C3, be aware that TSC/APIC timer may be * stopped by H/W. Without carefully handling of TSC/APIC stop issues, @@ -335,6 +348,8 @@ static void acpi_processor_idle(void) /* recovering TSC */ cstate_restore_tsc(); + /* Trace cpu idle exit */ + TRACE_1D(TRC_PM_IDLE_EXIT, cx - &power->states[0]); if ( power->flags.bm_check && power->flags.bm_control ) { diff --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c index 882a7cc452..a26e2518c3 100644 --- a/xen/drivers/cpufreq/utility.c +++ b/xen/drivers/cpufreq/utility.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -293,7 +294,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, int retval = -EINVAL; if (cpu_online(policy->cpu) && cpufreq_driver->target) + { + unsigned int prev_freq = policy->cur; + retval = cpufreq_driver->target(policy, target_freq, relation); + if ( retval == 0 ) + TRACE_2D(TRC_PM_FREQ_CHANGE, prev_freq/1000, policy->cur/1000); + } return retval; } diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h index a11b30f32c..5cce0287eb 100644 --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -38,6 +38,7 @@ #define TRC_MEM 0x0010f000 /* Xen memory trace */ #define TRC_PV 0x0020f000 /* Xen PV traces */ #define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */ +#define TRC_PM 0x0080f000 /* Xen power management trace */ #define TRC_ALL 0x0ffff000 #define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff) #define TRC_HD_CYCLE_FLAG (1UL<<31) @@ -146,6 +147,15 @@ #define TRC_HVM_LMSW (TRC_HVM_HANDLER + 0x19) #define TRC_HVM_LMSW64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x19) +/* trace subclasses for power management */ +#define TRC_PM_FREQ 0x00801000 /* xen cpu freq events */ +#define TRC_PM_IDLE 0x00802000 /* xen cpu idle events */ + +/* trace events for per class */ +#define TRC_PM_FREQ_CHANGE (TRC_PM_FREQ + 0x01) +#define TRC_PM_IDLE_ENTRY (TRC_PM_IDLE + 0x01) +#define TRC_PM_IDLE_EXIT (TRC_PM_IDLE + 0x02) + /* This structure represents a single trace buffer record. */ struct t_rec { uint32_t event:28; -- 2.30.2